package com.wuster.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wuster.entity.dto.UpdatePassDTO;
import com.wuster.entity.dto.UserLoginDTO;
import com.wuster.entity.dto.UserUpdateDTO;
import com.wuster.entity.vo.UserInfoVO;
import com.wuster.exception.AccountNotFoundException;
import com.wuster.constant.MessageConstant;

import com.wuster.entity.po.User;
import com.wuster.exception.PasswordErrorException;
import com.wuster.exception.UpdateFailedException;
import com.wuster.mapper.UserMapper;
import com.wuster.result.Result;
import com.wuster.service.UserService;
import com.wuster.utils.BaseContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.List;


@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;


    /**
     * 新增用户
     * @param userLoginDTO
     * @return
     */
    public Result save(UserLoginDTO userLoginDTO) {
        String number = userLoginDTO.getNumber();
        String password = userLoginDTO.getPassword();

        //查询该手机号是否已经注册
        User queryUser = selectUserByNumber(number);

        if (queryUser != null){
            //抛手机号已注册异常, 日志记录
            log.info("该手机号已注册:{}", number);
            return Result.error("该手机号已注册");
        }
        else if ("".equals(number) || number.length() != 11){
            log.info("该手机号不符合规范！:{}", number);
            return Result.error("手机号不符合规范！");
        }
        else {
            //根据前端传过来的数据对象创建新对象
            User user = new User();

            //对象属性拷贝, name默认设置为手机号
            BeanUtils.copyProperties(userLoginDTO, user);
            user.setUserName(number);

            //将明文密码进行加密，存储到数据库中
            user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));

            //调用mapper层新增用户
            userMapper.insert(user);
            return Result.success();
        }
    }


    /**
     * 用户登录
     * @param userLoginDTO
     * @return
     */
    public User login(UserLoginDTO userLoginDTO) {
        String number = userLoginDTO.getNumber();
        String password = userLoginDTO.getPassword();

        //手机号异常 报错
        if ("".equals(number) || number.length() != 11) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //根据手机号查询用户
        User queryUser = selectUserByNumber(number);
        //用户存在 密码比对
        if (queryUser != null){
            boolean res = verifyPass(password, queryUser.getPassword());
            if (!res) //抛出密码错误异常
                throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }
        //3、返回实体对象
        return queryUser;
    }

    /**
     * 核实密码
     * @param checkPass 前端传过来的明文密码
     */
    public Result checkPass(String checkPass) {
        User user = userMapper.selectById(BaseContext.getCurrentId());
        //密码为空判断
        if("".equals(checkPass))
            return Result.error("密码不能为空！");

        boolean status = verifyPass(checkPass, user.getPassword());

        if (status)
            return Result.success();
        return Result.error("密码错误！");
    }

    /**
     * 修改密码，修改密码前需要先核实旧密码是否正确
     * @param updatePassDTO
     * @return
     */
    public Result updatePass(UpdatePassDTO updatePassDTO) {
        Long uid = BaseContext.getCurrentId();
        String password = updatePassDTO.getPassword();
        String newPassword = updatePassDTO.getNewPassword();

        User user = userMapper.selectById(uid);
        //核实旧密码是否正确
        boolean b = verifyPass(password, user.getPassword());
        if (!b)
            return Result.error("原密码错误！");

        // 密码处理，将前端传来的明文密码进行加密 （使用java自带的方法）
        if ("".equals(newPassword))
            return Result.error("密码不能为空！");
        newPassword = DigestUtils.md5DigestAsHex(newPassword.getBytes());

        //更新密码
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", uid).set("password", newPassword);

        userMapper.update(user, updateWrapper);
        return Result.success();
    }


    /**
     * 获取用户个人信息
     * @param uid
     * @return
     */
    public UserInfoVO getInfo(Long uid) {
        //根据id查询用户
        User user = userMapper.selectById(uid);
        //将用户信息做处理后传给前端
        UserInfoVO userInfoVO = UserInfoVO.builder()
                .id(uid)
                .name(user.getUserName())
                .college(user.getAcademic())
                .speciality(user.getMajor())
                .grade(user.getGrade())
                .degree(user.getEduaction())
                .email(user.getEmail())
                .identity(user.getIdentity())
                .tutorName(user.getTutorName())
                .role(user.getRole())
                .build();
        return userInfoVO;
    }

    /**
     * 修改个人信息
     * @param userUpdateDTO
     * @return
     */
    public void updateInfo(UserUpdateDTO userUpdateDTO) {
        userUpdateDTO.setId(BaseContext.getCurrentId());
        // 更新用户信息
        try {
            LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<User>();
            //设置updateWrapper构造器
            updateWrapper.eq(User::getId, BaseContext.getCurrentId())
                    .set(User::getUserName, userUpdateDTO.getUserName())
                    .set(User::getAcademic, userUpdateDTO.getAcademic())
                    .set(User::getEmail, userUpdateDTO.getEmail())
                    .set(User::getMajor, userUpdateDTO.getMajor())
                    .set(User::getGrade, userUpdateDTO.getGrade())
                    .set(User::getEduaction, userUpdateDTO.getEduaction())
                    .set(User::getIdentity, userUpdateDTO.getIdentity())
                    .set(User::getTutorName, userUpdateDTO.getTutorName());

            userMapper.update(null, updateWrapper);    //第一个参数一定要设置null，这样就只会更新你set的字段。

        } catch (Exception e){
            new UpdateFailedException(MessageConstant.UPDATE_INFO_FAILED);
        }
    }


//--------------------------------------------------------------------------------------
    /**
     * 提取的方法（多个地方使用到），根据手机号查询用户
     * @param number
     * @return
     */
    public User selectUserByNumber(String number){
        // 使用 QueryWrapper 创建查询条件
        QueryWrapper<User> queryWrapper = Wrappers.query();
        // 使用 eq 方法添加条件
        queryWrapper.eq("number", number);
        User user = userMapper.selectOne(queryWrapper);
        return user;
    }


    /**
     * 提取的方法，明文密码与加密的密码比对
     * @param pass  明文密码
     * @param secretPass 加密的密码
     * @return
     */
    public boolean verifyPass(String pass, String secretPass){
        // 密码处理，将前端传来的明文密码进行加密 （使用java自带的方法）
        pass = DigestUtils.md5DigestAsHex(pass.getBytes());
        //与数据库中加密的密码比对
        if (!pass.equals(secretPass)) {
            //密码错误
            return false;
        }
        return true;
    }
}
